# -*- coding: utf-8 -*-
"""
角色管理器组件
"""

import math
from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QListWidget,
                             QPushButton, QLabel, QGraphicsView, QGraphicsScene,
                             QGraphicsEllipseItem, QGraphicsTextItem, QInputDialog,
                             QMessageBox, QListWidgetItem, QMenu, QTabWidget,
                             QLineEdit, QTextEdit, QTableWidget, QTableWidgetItem,
                             QHeaderView, QComboBox, QDialog, QSplitter,
                             QGraphicsLineItem)
from PySide6.QtCore import Qt, Signal, QPointF, QRectF, QTimer
from PySide6.QtGui import QBrush, QPen, QColor, QFont

from ..models.novel import Novel
from ..models.character import Character
from ..services.character_generator import CharacterGenerator


class CharacterNode(QGraphicsEllipseItem):
    """角色节点图形项"""
    
    def __init__(self, character: Character, x: float, y: float, radius: float = 30):
        super().__init__(-radius, -radius, radius * 2, radius * 2)
        self.character = character
        self.radius = radius
        self.click_timer = QTimer()
        self.click_timer.setSingleShot(True)
        self.click_timer.timeout.connect(self.single_click)
        self.click_count = 0
        
        # 设置样式
        self.setBrush(QBrush(QColor(100, 150, 200)))
        self.setPen(QPen(QColor(50, 100, 150), 2))
        self.setFlag(QGraphicsEllipseItem.ItemIsMovable, True)
        self.setFlag(QGraphicsEllipseItem.ItemIsSelectable, True)
        
        # 设置位置
        self.setPos(x, y)
        
        # 添加文本标签
        self.text_item = QGraphicsTextItem(self)
        self.text_item.setPlainText(character.name)
        self.text_item.setPos(-radius, -radius - 20)
        
        font = QFont("Microsoft YaHei", 10)
        self.text_item.setFont(font)
    
    def mousePressEvent(self, event):
        """鼠标按下事件"""
        if event.button() == Qt.LeftButton:
            self.click_count += 1
            if self.click_count == 1:
                self.click_timer.start(300)  # 300ms内检测双击
            elif self.click_count == 2:
                self.click_timer.stop()
                self.double_click()
                self.click_count = 0
        super().mousePressEvent(event)
    
    def single_click(self):
        """单击处理"""
        self.click_count = 0
    
    def double_click(self):
        """双击处理"""
        # 发射双击信号
        scene = self.scene()
        if hasattr(scene, 'character_double_clicked'):
            scene.character_double_clicked.emit(self.character)
    
    def mouseMoveEvent(self, event):
        """鼠标移动事件"""
        super().mouseMoveEvent(event)
        # 更新角色位置
        pos = self.pos()
        self.character.set_position(pos.x(), pos.y())
        # 更新关系连线
        scene = self.scene()
        if hasattr(scene, 'update_relationships'):
            scene.update_relationships()


class CharacterScene(QGraphicsScene):
    """角色关系图场景"""
    
    character_double_clicked = Signal(Character)
    
    def __init__(self):
        super().__init__()
        self.character_nodes = {}  # character_id -> CharacterNode
        self.relationship_lines = []  # 存储关系连线
        self.setSceneRect(-300, -300, 600, 600)
    
    def update_relationships(self):
        """更新关系连线"""
        # 清除旧的连线
        for line in self.relationship_lines:
            self.removeItem(line)
        self.relationship_lines.clear()
        
        # 重新绘制连线
        for char_id, node in self.character_nodes.items():
            character = node.character
            for rel in character.relationships:
                target_node = self.character_nodes.get(rel['target_id'])
                if target_node:
                    self.draw_relationship_line(node, target_node, rel['type'])
    
    def draw_relationship_line(self, source_node, target_node, rel_type):
        """绘制关系连线"""
        # 计算连线位置（从圆边缘到圆边缘）
        source_pos = source_node.pos()
        target_pos = target_node.pos()
        
        # 计算方向向量
        dx = target_pos.x() - source_pos.x()
        dy = target_pos.y() - source_pos.y()
        distance = (dx*dx + dy*dy) ** 0.5
        
        if distance == 0:
            return
        
        # 单位向量
        ux = dx / distance
        uy = dy / distance
        
        # 起点和终点（从圆边缘开始）
        radius = source_node.radius
        start_x = source_pos.x() + ux * radius
        start_y = source_pos.y() + uy * radius
        end_x = target_pos.x() - ux * radius
        end_y = target_pos.y() - uy * radius
        
        # 绘制连线
        line = QGraphicsLineItem(start_x, start_y, end_x, end_y)
        line.setPen(QPen(QColor(150, 150, 150), 2))
        self.addItem(line)
        self.relationship_lines.append(line)
        
        # 添加关系标签
        mid_x = (start_x + end_x) / 2
        mid_y = (start_y + end_y) / 2
        
        text = self.addText(rel_type, QFont("Microsoft YaHei", 8))
        text.setPos(mid_x - 20, mid_y - 10)
        self.relationship_lines.append(text)


class CharacterRelationView(QGraphicsView):
    """角色关系图视图"""
    
    character_double_clicked = Signal(Character)
    
    def __init__(self, novel: Novel):
        super().__init__()
        self.novel = novel
        self.scene = CharacterScene()
        self.setScene(self.scene)
        
        # 连接信号
        self.scene.character_double_clicked.connect(self.character_double_clicked)
        
        self.load_characters()
    
    def set_novel(self, novel: Novel):
        """设置小说"""
        self.novel = novel
        self.load_characters()
    
    def load_characters(self):
        """加载角色到关系图"""
        self.scene.clear()
        self.scene.character_nodes.clear()
        self.scene.relationship_lines.clear()
        
        if not self.novel or not self.novel.characters:
            return
        
        # 为没有位置的角色安排位置
        self.arrange_characters()
        
        # 创建角色节点
        for character in self.novel.characters:
            x, y = character.position
            node = CharacterNode(character, x, y)
            self.scene.addItem(node)
            self.scene.character_nodes[character.id] = node
        
        # 绘制关系连线
        self.scene.update_relationships()
    
    def arrange_characters(self):
        """为角色安排位置（圆形布局）"""
        characters_without_position = [
            char for char in self.novel.characters 
            if char.position == (0.0, 0.0)
        ]
        
        if not characters_without_position:
            return
        
        count = len(characters_without_position)
        radius = 150
        
        for i, character in enumerate(characters_without_position):
            angle = 2 * math.pi * i / count
            x = radius * math.cos(angle)
            y = radius * math.sin(angle)
            character.set_position(x, y)


class CharacterAttributeEditor(QWidget):
    """角色属性编辑器"""
    
    def __init__(self, character: Character = None):
        super().__init__()
        self.character = character
        self.init_ui()
        if character:
            self.load_character()
    
    def init_ui(self):
        """初始化界面"""
        layout = QVBoxLayout(self)
        
        # 角色基本信息
        info_layout = QVBoxLayout()
        
        # 角色名字
        name_layout = QHBoxLayout()
        name_layout.addWidget(QLabel("角色名字:"))
        self.name_edit = QLineEdit()
        name_layout.addWidget(self.name_edit)
        info_layout.addLayout(name_layout)
        
        # 角色描述
        desc_layout = QVBoxLayout()
        desc_layout.addWidget(QLabel("角色描述:"))
        self.desc_edit = QTextEdit()
        self.desc_edit.setMaximumHeight(100)
        desc_layout.addWidget(self.desc_edit)
        info_layout.addLayout(desc_layout)
        
        layout.addLayout(info_layout)
        
        # 属性表格
        attr_layout = QVBoxLayout()
        attr_header = QHBoxLayout()
        attr_header.addWidget(QLabel("角色属性:"))
        attr_header.addStretch()
        
        add_attr_btn = QPushButton("添加属性")
        add_attr_btn.clicked.connect(self.add_attribute)
        attr_header.addWidget(add_attr_btn)
        
        attr_layout.addLayout(attr_header)
        
        # 属性表格
        self.attr_table = QTableWidget()
        self.attr_table.setColumnCount(3)
        self.attr_table.setHorizontalHeaderLabels(["标签", "描述", "内容"])
        self.attr_table.horizontalHeader().setStretchLastSection(True)
        self.attr_table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.attr_table.customContextMenuRequested.connect(self.show_attr_context_menu)
        attr_layout.addWidget(self.attr_table)
        
        layout.addLayout(attr_layout)
        
        # 保存按钮
        save_btn = QPushButton("保存")
        save_btn.clicked.connect(self.save_character)
        layout.addWidget(save_btn)
    
    def set_character(self, character: Character):
        """设置要编辑的角色"""
        self.character = character
        self.load_character()
    
    def load_character(self):
        """加载角色信息"""
        if not self.character:
            return
        
        self.name_edit.setText(self.character.name)
        self.desc_edit.setPlainText(self.character.description)
        
        # 加载属性
        self.attr_table.setRowCount(len(self.character.attributes))
        for i, attr in enumerate(self.character.attributes):
            self.attr_table.setItem(i, 0, QTableWidgetItem(attr.get('label', '')))
            self.attr_table.setItem(i, 1, QTableWidgetItem(attr.get('desc', '')))
            self.attr_table.setItem(i, 2, QTableWidgetItem(attr.get('content', '')))
    
    def add_attribute(self):
        """添加属性"""
        row = self.attr_table.rowCount()
        self.attr_table.insertRow(row)
        self.attr_table.setItem(row, 0, QTableWidgetItem(""))
        self.attr_table.setItem(row, 1, QTableWidgetItem(""))
        self.attr_table.setItem(row, 2, QTableWidgetItem(""))
    
    def show_attr_context_menu(self, pos):
        """显示属性右键菜单"""
        row = self.attr_table.rowAt(pos.y())
        if row >= 0:
            menu = QMenu(self)
            delete_action = menu.addAction("删除属性")
            delete_action.triggered.connect(lambda: self.delete_attribute(row))
            menu.exec(self.attr_table.mapToGlobal(pos))
    
    def delete_attribute(self, row):
        """删除属性"""
        self.attr_table.removeRow(row)
    
    def save_character(self):
        """保存角色信息"""
        if not self.character:
            return
        
        # 保存基本信息
        self.character.name = self.name_edit.text()
        self.character.description = self.desc_edit.toPlainText()
        
        # 保存属性
        self.character.attributes.clear()
        for i in range(self.attr_table.rowCount()):
            label_item = self.attr_table.item(i, 0)  
            desc_item = self.attr_table.item(i, 1)
            content_item = self.attr_table.item(i, 2)
            
            if label_item:  # 至少标签不能为空
                self.character.add_attribute(
                    label_item.text() if label_item else "",
                    desc_item.text() if desc_item else "",
                    content_item.text() if content_item else ""
                )


class AINameGeneratorDialog(QDialog):
    """AI名字生成器对话框"""
    
    def __init__(self, ai_writer, existing_names, parent=None):
        super().__init__(parent)
        self.ai_writer = ai_writer
        self.existing_names = set(existing_names)
        self.generated_names = []
        self.selected_name = ""
        
        self.init_ui()
    
    def init_ui(self):
        """初始化界面"""
        self.setWindowTitle("AI角色名字生成器")
        self.setMinimumSize(400, 500)
        
        layout = QVBoxLayout(self)
        
        # 生成参数
        params_layout = QVBoxLayout()
        params_layout.addWidget(QLabel("生成参数:"))
        
        # 角色类型
        type_layout = QHBoxLayout()
        type_layout.addWidget(QLabel("角色类型:"))
        self.type_edit = QLineEdit()
        self.type_edit.setPlaceholderText("例如：现代都市青年、古代武侠侠客、科幻未来战士...")
        type_layout.addWidget(self.type_edit)
        params_layout.addLayout(type_layout)
        
        # 数量设置
        count_layout = QHBoxLayout()
        count_layout.addWidget(QLabel("生成数量:"))
        self.count_spin = QComboBox()
        self.count_spin.addItems(["5", "10", "15", "20"])
        self.count_spin.setCurrentText("10")
        count_layout.addWidget(self.count_spin)
        count_layout.addStretch()
        params_layout.addLayout(count_layout)
        
        layout.addLayout(params_layout)
        
        # 生成按钮
        generate_btn = QPushButton("生成名字")
        generate_btn.clicked.connect(self.generate_names)
        layout.addWidget(generate_btn)
        
        # 搜索框
        search_layout = QHBoxLayout()
        search_layout.addWidget(QLabel("搜索:"))
        self.search_edit = QLineEdit()
        self.search_edit.setPlaceholderText("输入关键词搜索名字...")
        self.search_edit.textChanged.connect(self.filter_names)
        search_layout.addWidget(self.search_edit)
        layout.addLayout(search_layout)
        
        # 名字列表
        self.name_list = QListWidget()
        self.name_list.itemDoubleClicked.connect(self.select_name)
        layout.addWidget(self.name_list)
        
        # 按钮
        button_layout = QHBoxLayout()
        
        use_btn = QPushButton("使用选中的名字")
        use_btn.clicked.connect(self.use_selected_name)
        button_layout.addWidget(use_btn)
        
        button_layout.addStretch()
        
        cancel_btn = QPushButton("取消")
        cancel_btn.clicked.connect(self.reject)
        button_layout.addWidget(cancel_btn)
        
        layout.addLayout(button_layout)
    
    def generate_names(self):
        """生成名字"""
        if not self.ai_writer.is_available():
            QMessageBox.warning(self, "警告", "AI服务不可用，请检查API配置")
            return
        
        character_type = self.type_edit.text().strip()
        count = int(self.count_spin.currentText())
        
        if not character_type:
            character_type = "普通角色"
        
        # 构建AI提示
        prompt = f"""请为小说生成{count}个{character_type}的名字。要求：
1. 名字要符合角色类型特点
2. 每个名字单独一行
3. 名字要有创意和个性
4. 适合中文小说
5. 不要添加编号或其他说明文字

请直接输出名字列表："""

        try:
            # 使用AI生成名字
            result = self.ai_writer.improve_text("", prompt)
            if result:
                # 解析生成的名字
                names = [name.strip() for name in result.split('\n') if name.strip()]
                self.generated_names = names
                self.display_names()
            else:
                QMessageBox.warning(self, "失败", "AI生成名字失败")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"生成名字时出错: {str(e)}")
    
    def display_names(self):
        """显示名字列表"""
        self.name_list.clear()
        
        for name in self.generated_names:
            display_text = name
            if name in self.existing_names:
                display_text += " (已使用)"
            
            item = QListWidgetItem(display_text)
            item.setData(Qt.UserRole, name)
            self.name_list.addItem(item)
    
    def filter_names(self):
        """过滤名字"""
        search_text = self.search_edit.text().lower()
        
        for i in range(self.name_list.count()):
            item = self.name_list.item(i)
            name = item.data(Qt.UserRole).lower()
            item.setHidden(search_text not in name)
    
    def select_name(self, item):
        """选择名字"""
        self.selected_name = item.data(Qt.UserRole)
        self.accept()
    
    def use_selected_name(self):
        """使用选中的名字"""
        current_item = self.name_list.currentItem()
        if current_item:
            self.selected_name = current_item.data(Qt.UserRole)
            self.accept()
        else:
            QMessageBox.warning(self, "警告", "请先选择一个名字")
    
    def get_selected_name(self):
        """获取选中的名字"""
        return self.selected_name


class CharacterManager(QWidget):
    """角色管理器主组件"""
    
    character_updated = Signal()
    
    def __init__(self, novel: Novel, character_generator: CharacterGenerator, ai_writer=None):
        super().__init__()
        self.novel = novel
        self.character_generator = character_generator
        self.ai_writer = ai_writer
        
        self.init_ui()
        self.load_characters()
    
    def init_ui(self):
        """初始化用户界面"""
        layout = QVBoxLayout(self)
        
        # 创建标签页
        self.tab_widget = QTabWidget()
        layout.addWidget(self.tab_widget)
        
        # 角色列表标签页
        self.create_character_list_tab()
        
        # 关系图标签页
        self.create_relation_view_tab()
    
    def create_character_list_tab(self):
        """创建角色列表标签页"""
        list_widget = QWidget()
        layout = QVBoxLayout(list_widget)
        
        # 工具栏
        toolbar = QHBoxLayout()
        toolbar.addWidget(QLabel("角色管理"))
        toolbar.addStretch()
        
        # AI生成名字按钮
        if self.ai_writer:
            ai_generate_btn = QPushButton("AI生成名字")
            ai_generate_btn.clicked.connect(self.ai_generate_character_names)
            toolbar.addWidget(ai_generate_btn)
        
        # 生成名字按钮
        generate_btn = QPushButton("随机生成名字")
        generate_btn.clicked.connect(self.generate_character_names)
        toolbar.addWidget(generate_btn)
        
        # 添加角色按钮
        add_btn = QPushButton("手动添加角色")
        add_btn.clicked.connect(self.add_character)
        toolbar.addWidget(add_btn)
        
        layout.addLayout(toolbar)
        
        # 角色列表
        self.character_list = QListWidget()
        self.character_list.itemDoubleClicked.connect(self.edit_character)
        self.character_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.character_list.customContextMenuRequested.connect(self.show_character_context_menu)
        layout.addWidget(self.character_list)
        
        self.tab_widget.addTab(list_widget, "角色列表")
    
    def create_relation_view_tab(self):
        """创建关系图标签页"""
        self.relation_view = CharacterRelationView(self.novel)
        self.relation_view.character_double_clicked.connect(self.edit_character_by_obj)
        self.tab_widget.addTab(self.relation_view, "关系图")
    
    def set_novel(self, novel: Novel):
        """设置小说"""
        self.novel = novel
        self.load_characters()
        self.relation_view.set_novel(novel)
    
    def set_ai_writer(self, ai_writer):
        """设置AI写作服务"""
        self.ai_writer = ai_writer
    
    def load_characters(self):
        """加载角色列表"""
        self.character_list.clear()
        if not self.novel:
            return
        
        for character in self.novel.characters:
            item = QListWidgetItem(character.name)
            item.setData(Qt.UserRole, character.id)
            self.character_list.addItem(item)
    
    def ai_generate_character_names(self):
        """AI生成角色名字"""
        if not self.ai_writer:
            QMessageBox.warning(self, "警告", "AI服务不可用")
            return
        
        # 获取已有角色名字
        existing_names = [char.name for char in self.novel.characters] if self.novel else []
        
        dialog = AINameGeneratorDialog(self.ai_writer, existing_names, self)
        if dialog.exec() == QDialog.Accepted:
            name = dialog.get_selected_name()
            if name:
                character = self.novel.add_character(name)
                self.load_characters()
                self.relation_view.load_characters()
                self.character_updated.emit()
    
    def generate_character_names(self):
        """随机生成角色名字"""
        names = self.character_generator.generate_names(5, "chinese", "random")
        
        # 显示选择对话框
        name, ok = QInputDialog.getItem(self, "选择角色名字", "生成的名字:", names, 0, False)
        if ok and name:
            character = self.novel.add_character(name)
            self.load_characters()
            self.relation_view.load_characters()
            self.character_updated.emit()
    
    def add_character(self):
        """手动添加角色"""
        name, ok = QInputDialog.getText(self, "添加角色", "请输入角色名字:")
        if ok and name.strip():
            character = self.novel.add_character(name.strip())
            self.load_characters()
            self.relation_view.load_characters()
            self.character_updated.emit()
    
    def edit_character(self, item: QListWidgetItem):
        """编辑角色"""
        character_id = item.data(Qt.UserRole)
        character = None
        
        for char in self.novel.characters:
            if char.id == character_id:
                character = char
                break
        
        if character:
            self.edit_character_by_obj(character)
    
    def edit_character_by_obj(self, character: Character):
        """通过角色对象编辑角色"""
        from .character_dialog import CharacterEditDialog
        dialog = CharacterEditDialog(character, self)
        if dialog.exec() == QDialog.Accepted:
            self.load_characters()
            self.relation_view.load_characters()
            self.character_updated.emit()
    
    def show_character_context_menu(self, pos):
        """显示角色右键菜单"""
        item = self.character_list.itemAt(pos)
        if item:
            menu = QMenu(self)
            
            edit_action = menu.addAction("编辑")
            edit_action.triggered.connect(lambda: self.edit_character(item))
            
            delete_action = menu.addAction("删除")
            delete_action.triggered.connect(lambda: self.delete_character(item.data(Qt.UserRole)))
            
            menu.exec(self.character_list.mapToGlobal(pos))
    
    def delete_character(self, character_id: str):
        """删除角色"""
        reply = QMessageBox.question(self, "确认删除", 
                                   "确定要删除这个角色吗？此操作不可撤销。",
                                   QMessageBox.Yes | QMessageBox.No,
                                   QMessageBox.No)
        
        if reply == QMessageBox.Yes:
            if self.novel.remove_character(character_id):
                self.load_characters()
                self.relation_view.load_characters()
                self.character_updated.emit() 